<?php

namespace app;

use think\Request;

/**
 * 参数类
 * 所有请求中的参数都是在这里进行验证和获取的
 * Class Param
 * @package app
 */
class Param extends Api
{
    protected $_parameters; // 参数

    public function _initialize()
    {
        parent::_initialize();
        $this->_parameters = $this->_createParameters();
    }

    /**
     * 获取参数
     * @param $key
     * @param string $default
     * @return string
     */
    protected function _getParams($key, $default = '')
    {
        if (isset($this->_parameters[$key])) {
            return $this->_parameters[$key];
        } else {
            return $default;
        }
    }

    /**
     * 获取业务参数
     * @param $key
     * @param string $default
     * @return string
     */
    protected function _getContentParams($key, $default = '')
    {
        $arr_content = $this->_getParams('content');
        if (isset($arr_content[$key])) {
//            $this->requestLogger($arr_content);
            if (is_array($arr_content[$key])) return '';
            return trim($arr_content[$key]);
        } else {
            return $default;
        }
    }

    /**
     * 获取参数，同时检查令牌正确性
     * @access protected
     * @since 1.0
     * @return mixed
     * $note $key 字段名称 用逗号隔开，如 'id,name,sex'
     */
    protected function _createParameters()
    {
        // appSecret
        // content字段中的数据必须为json类型且经过URL编码
        // 获取所有数据
        $arr_param = [];

        $arr_param['appId'] = Request::instance()->param('appId', '');
        $arr_param['content'] = Request::instance()->param('content', '');
        $arr_param['timestamp'] = Request::instance()->param('timestamp', '');
        $arr_param['platform'] = Request::instance()->param('platform', '');
        $arr_param['version'] = Request::instance()->param('version', '');
        $t = Request::instance()->param('t', '');

        if ($t == 'test') {
            // content 请求参数的集合，最大长度不限，除公共参数外所有请求参数都必须放在这个参数中传递(json)
            $arr_param['content'] = (array)json_decode(urldecode($arr_param['content']), true);

            _toCompare(!in_array($arr_param['platform'], ['app', 'web']), '===', true, 10004);

            return $arr_param;
        }

        // 获取appSecret
        $appSecret = $this->getAppSecret($arr_param['appId']);
        $sys_sign = $this->_createParamKey($arr_param, $appSecret);
        $user_sign = Request::instance()->param('sign', '');

        //------验证 start-------
        _toCompare($sys_sign, '!=', $user_sign, 10001);
        _toValidate('time', $arr_param['timestamp'], 10002);
        _toCompare((strtotime($arr_param['timestamp']) > strtotime($this->_now) - 18000) && (strtotime($arr_param['timestamp']) < strtotime($this->_now) + 18000), '!=', true, 10002);
        _toCompare(!in_array($arr_param['version'], ['v1.0.0']), '===', true, 10003);
        _toCompare(!in_array($arr_param['platform'], ['app', 'web']), '===', true, 10004);
        //------验证 end -------

        // content 请求参数的集合，最大长度不限，除公共参数外所有请求参数都必须放在这个参数中传递(json)
        $arr_param['content'] = (array)json_decode(urldecode($arr_param['content']), true);

        return $arr_param;
    }


    /**
     * 获取appSecret
     * @param $app_id
     * @return mixed
     */
    private function getAppSecret($app_id)
    {
        $arr_all_app_id = [
            'mx783892173d4xst3264' => 'c33940739173ba290d6bj03f737e1397', // 目前是写死的 之后必须要进行整改
        ];

        // 如果不存在$app_id，就报错
        _toCompare(!in_array($app_id, array_keys($arr_all_app_id)), '===', true, 10001);

        // 如果不存在 $all_app_id[$app_id]，就报错
        _toCompare(!isset($arr_all_app_id[$app_id]), '===', true, 10001);

        return $arr_all_app_id[$app_id];
    }


    /**
     * 生成签名
     * @param $param
     * @param $app_secret
     * @return string
     */
    private function _createParamKey(array $arr_param, $app_secret)
    {

        if ($arr_param['content'] == '') {
            unset($arr_param['content']);
        } else if (urldecode($arr_param['content']) == $arr_param['content']) {
            $arr_param['content'] = urlencode($arr_param['content']);
        }

        ksort($arr_param);//根据键值升序排列

        $sign = '';

        foreach ($arr_param as $key => $value) {
            $sign .= $key . '=' . $value . '&';
        }
        $sign .= $app_secret;
//        echo $sign;exit;
        return strtoupper(md5($sign));
    }

    /**
     * 请求日志生成日志
     * @access public
     * @param string $log_content 日志内容
     * @since 1.0
     */
    private function requestLogger($log_content)
    {
        $log_filename = "log_request_" . date('Ymd') . ".xml";
        file_put_contents($log_filename, date('Y-m-d H:i:s') . "----" . $log_content . "\r\n\r\n", FILE_APPEND);
    }
}
